package inherit;

/**
 * @User: vitobo
 * @Date: 2024-05-21
 * @Description:
 */

/**
 * 1. 当子类和父类的成员变量同名的时候,就要访问父类的, 怎么办?
 *
 * 2. 当子类和父类的成员方法同名的时候,访问父类的方法,怎么办?
 *    super关键字  super是获取到子类对象中 从基类继承下来的部分
 *
 * 3. super和this的区别是什么?
 *      1.都是Java当中的关键字
 *      2.只能在类的非静态方法中使用,用来访问非静态成员方法和字段
 *      3.在构造方法调用时,必须是构造方法中的第一条语句,并且不能同时存在
 *    不同点:
 *      this是当前对象的引用,当前对象即调用实例方法的对象; super相当于是子类对象中从父类继承下来部分成员的引用
 *      在非静态成员方法中，this用来访问本类的方法和属性，super用来访问父类继承下来的方法和属性
 *       在构造方法中：this(...)用于调用本类构造方法，super(...)用于调用父类构造方法，两种调用不能同时在构造
 * 方法中出现
 *      构造方法中一定会存在super(...)的调用，用户没有写编译器也会增加，但是this(...)用户不写则没有
 *
 *
 *  1. this会优先访问子类自己的,如果子类没有,访问的是父类的
 *  2. super只是一个关键字,在代码层面上, 能够达到易读的效果; 在子类当中访问父类的成员
 *       super.data 访问父类的普通成员变量
 *       super.func() 访问父类的普通成员方法
 *       super() 调用父类的构造方法
 *
 *
 * 3. 实例代码块, 静态代码块,构造方法执行顺序:
 *      1.静态代码块先执行,并且只执行一次, 在类加载阶段执行
 *      2.当有对象创建时,才会执行实例代码块, 实例代码块执行完成后,最后构造方法执行
 *
 *      在继承关系上的执行:
 *          1、父类静态代码块优先于子类静态代码块执行，且是最早执行
 *          2、父类实例代码块和父类构造方法紧接着执行
 *          3、子类的实例代码块和子类构造方法紧接着再执行
 *          4、第二次实例化子类对象时，父类和子类的静态代码块都将不会再执行
 * 4.protected关键字
 *
 *
 *
 * 5.类的修饰符为什么只能是public, 或者什么都不写?
 *   在 Java 中，一个源文件里只能有一个 public 类，这个 public 类的类名必须与文件名相同。
 *   这是因为 Java 文件的编译后会生成对应的类文件，而类文件是由类名来命名的，
 *   如果有多个 public 类且类名不同，则无法确定生成的类文件的名称，这会造成混乱。
 *
 *
 * 6. final关键字, 修饰的不能再被修改
 *      1.修饰变量或字段时,表示常量(不能被修改)
 *      2.修饰类:表示此类不能被继承
 *      3.修饰方法:表示该方法不能被重写
 *
 * 7. 继承与组合:
 *      继承可以看作is-a的关系,
 *      组合 has a 的关系  学校有老师和学生
 *    根据应用场景来选择,尽量使用组合
 */





class Base{
    int a;
    int b;

    public void methodA(int a){
        System.out.println("Base中的methodA()方法");
    }
}


public class Derived extends Base{
    int a;
    int c;

    public void methodA(){
        System.out.println("Derived::methodA()");
    }
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    public void methodC(){
        methodB();  // 访问子类自己的
        methodA();  // 访问父类继承的
    }

    public void method(){
        // 当 父类和子类 都拥有同名的变量的时候, 优先访问子类自己
        super.a = 10;
        b = 20;
        c = 30;
        System.out.println(super.a);
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }



    public static void main(String[] args) {
        Derived derived = new Derived();
        // derived.method();

        derived.methodC();

//        Base base = new Base();
//        System.out.println(base.a);
    }
}
